import { Inject, Provide } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository, Between, Not, In, LessThan } from 'typeorm';
import { AppointmentInfoEntity } from '../entity/info';
import { CoolCommException } from '@cool-midway/core';
import { BaseSysUserEntity } from '../../base/entity/sys/user';
import { DictInfoEntity } from '../../dict/entity/info';
import { UserInfoEntity } from '../../user/entity/info';
import { AppointmentLimitEntity } from '../entity/limit';

/**
 * 预约信息
 */
@Provide()
export class AppointmentInfoService extends BaseService {
  @InjectEntityModel(AppointmentInfoEntity)
  appointmentInfoEntity: Repository<AppointmentInfoEntity>;

  @InjectEntityModel(BaseSysUserEntity)
  baseSysUserEntity: Repository<BaseSysUserEntity>;

  @InjectEntityModel(DictInfoEntity)
  dictInfoEntity: Repository<DictInfoEntity>;

  @InjectEntityModel(UserInfoEntity)
  userInfoEntity: Repository<UserInfoEntity>;

  @InjectEntityModel(AppointmentLimitEntity)
  appointmentLimitEntity: Repository<AppointmentLimitEntity>;


  @Inject()
  ctx;




  /**
   * 取消预约
   */
  async appointCancle(param: {
    appointId: number;
  }) {
    const appointInfo = await this.appointmentInfoEntity.findOne({
      where: {
        id: param.appointId,
      },
    });
    if (!appointInfo) {
      throw new CoolCommException('预约信息不存在');
    }
    appointInfo.appointmentStatus = 4;
    appointInfo.updateTime = new Date();
    return await this.appointmentInfoEntity.save(appointInfo);
  }

  /**
   * 预约
   * @param studentId
   * @param doctorId
   * @param shopId
   * @param date
   * @param time
   */
  async appoint(param: {
    studentId?: number;    // 学生ID
    doctorId?: number;     // 医生ID
    shopId: number;       // 门店ID
    date: string;  // 预约日期
    time: string;  // 预约时间
    ignoreConflict?: boolean; // 是否忽略冲突
  }) {
    // 检查是否有未来的预约
    const now = new Date();
    const currentTime = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const appointmentTime = new Date(`${param.date} ${param.time}`);
    console.log('appointmentTime', appointmentTime, param);

    // 查询当天是否有预约限制
    const limits = await this.appointmentLimitEntity.find({
      where: {
        shopId: param.shopId,
        week: appointmentTime.getDay(),
        type: 0,
      }
    });

    if (limits.length > 0) {
      // 根据限制的时间，限制的时间也不可以预约
      if (limits[0].time) {
        const timeArr = limits[0].time.split(',');
        if (timeArr.includes(param.time)) {
          throw new CoolCommException('该时间段不可预约');
        }
      }
    }


    const existingAppointment = await this.appointmentInfoEntity.findOne({
      where: {
        studentId: param.studentId,
        appointmentTime: Between(currentTime, new Date('2099-12-31')),
        appointmentStatus: Not(In([1, 2, 4]))  // 排除已取消的预约
      }
    });

    

    // 如果不是后台预约的，不能预约已过时间
    if (!this.ctx.admin && appointmentTime < now) {
      throw new CoolCommException('不能预约过去的时间');
    } 

    // 如果不是后台操作，并且已经有预约的，则不能改约
    if (!this.ctx.admin && existingAppointment) {
      throw new CoolCommException('您已预约，请联系招募老师帮忙改约');
    }

    // 检查该时间是否已被预约
    
    const conflictAppointment = await this.appointmentInfoEntity.findOne({
      where: {
        shopId: param.shopId,
        appointmentStatus: Not(In([2, 4])),
        appointmentTime: appointmentTime
      }
    });
    if (conflictAppointment && !param.ignoreConflict) {
      throw new CoolCommException('该时间已被预约，请选择其他时间');
    }

    // 检查是否有历史预约
    const hasHistoryAppointment = await this.appointmentInfoEntity.findOne({
      where: {
        studentId: param.studentId,
        appointmentStatus: In([1, 5]),
      }
    });

    const appointInfo = new AppointmentInfoEntity();
    appointInfo.studentId = param.studentId;
    appointInfo.doctorId = param.doctorId;
    appointInfo.shopId = param.shopId;
    appointInfo.appointmentTime = new Date(`${param.date} ${param.time}`);
    appointInfo.createTime = new Date();
    appointInfo.updateTime = new Date();
    appointInfo.appointmentType = hasHistoryAppointment ? 1 : 0;  // 如果有历史预约则设为复诊
    if (this.ctx.admin) {
      appointInfo.adminId = this.ctx.admin.userId;
    }
    // 先保存新预约
    const savedAppointment = await this.appointmentInfoEntity.save(appointInfo);
    // 将新预约ID保存到用户的最近预约ID
    if (savedAppointment) {
      const user = await this.userInfoEntity.findOne({
        where: {
          id: param.studentId,
        }
      });
      if (user) {
        user.shopId = param.shopId;
        user.lastAppointId = savedAppointment.id;
        await this.userInfoEntity.save(user);
      }
    }
    // 新预约保存成功后，取消旧预约
    if (savedAppointment && existingAppointment) {
      existingAppointment.appointmentStatus = 2;
      existingAppointment.updateTime = new Date();
      if (this.ctx.admin) {
        existingAppointment.cancleAdminId = this.ctx.admin.userId;
      }
      await this.appointmentInfoEntity.save(existingAppointment);
    }

    return await this.appointmentInfoEntity.save(appointInfo);
  }

  /**
   * 查看预约
   * @param studentId
   * @param doctorId
   * @param shopId
   * @param date
   */
  async dateAppoint(param: {
    shopId: number;       // 门店ID
    date: string;  // 预约日期
    doctorId: number;     // 医生ID
    endDate?: string;  // 结束日期
  }) {
    const startDate = new Date(`${param.date} 00:00:00`);
    const endDate = param.endDate 
      ? new Date(`${param.endDate} 23:59:59`)
      : new Date(`${param.date} 23:59:59`);
    // console.log('dateAppoint service', startDate, endDate);
    const appointInfo = await this.appointmentInfoEntity.find({
      select: ['id', 'appointmentTime', 'studentId', 'appointmentStatus'],
      where: {
        shopId: param.shopId,
        appointmentStatus: Not(In([2, 4])),
        appointmentTime: Between(startDate, endDate),
      },
    });

    // 获取所有相关学生的信息
    const studentIds = appointInfo.map(appoint => appoint.studentId);
    const students = await this.userInfoEntity.find({
      select: ['id', 'nickName'],
      where: {
        id: In(studentIds)
      }
    });
    // 将学生信息添加到预约信息中
    const result = appointInfo.map(appoint => ({
      id: appoint.id,
      studentId: appoint.studentId,
      appointmentStatus: appoint.appointmentStatus,
      appointmentTime: appoint.appointmentTime,
      userName: students.find(student => student.id === appoint.studentId)?.nickName || '已预约'
    }));

    return result;
  }

  /**
   * 已经到店
   */
  async appointCome(param: {
    appointId: number;
  }) {
    const appointInfo = await this.appointmentInfoEntity.findOne({
      where: {
        id: param.appointId,
      },
    });
    if (!appointInfo) {
      throw new CoolCommException('预约信息不存在');
    }
    appointInfo.appointmentStatus = appointInfo.appointmentStatus === 1 ? 0 : 1;
    appointInfo.updateTime = new Date();
    return await this.appointmentInfoEntity.save(appointInfo);
  }

  // 限制门店星期的预约人数
  async updateShopWeekLimit(param) {
    // 查看是否已经有限制
    param.limit = 99;
    const limit = await this.appointmentLimitEntity.findOne({
      where: {
        shopId: param.shopId,
        week: param.week,
        type: 0
      }
    });
    if (limit) {
      param.id = limit.id;
    }
    param.operatorId = this.ctx.admin.userId;
    return await this.appointmentLimitEntity.save(param);
  }

  // 根据门店获取限制的星期数组
  async getShopWeekLimit(shopId) {
    const limits = await this.appointmentLimitEntity.find({
      where: {
        shopId,
        type: 0,
      }
    });
    return limits;
  }
}
